package top.guoyang.springboot3.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.guoyang.springboot3.annotation.BucketLimit;
import top.guoyang.springboot3.annotation.Limit;
import top.guoyang.springboot3.annotation.LimitMode;
import top.guoyang.springboot3.service.LimitService;
import top.guoyang.springboot3.service.RedisService;
import top.guoyang.springboot3.util.IpUtils;

@Service
@RequiredArgsConstructor
@Slf4j
public class LimitServiceImpl implements LimitService {
    private final RedisService redisService;

    @Override
    public boolean check(Limit limit) {
        //拼接保存在redis中的key
        String key = String.format("limit_%s_%s", IpUtils.getIpAddress(), limit.key());
        //如果key存在就表示还在限流中
        if (redisService.has(key)) {
            return false;
        }
        //如果不存在就添加限流信息
        redisService.save(key, "limit", limit.timeout());
        return true;
    }

    @Override
    public boolean check(BucketLimit limit) {
        //默认为ip桶
        String key = String.format("limit_%s_%s", IpUtils.getIpAddress(), limit.key());
        if (LimitMode.GLOBAL.equals(limit.mode())) {
            key = String.format("bucket_limit_%s_%s", "global", limit.key());
        }
        //如果key不存在
        if (!redisService.has(key)) {
            //计数器为1
            redisService.save(key, 1, limit.timeout());
            return true;
        }
        //校验次数
        Integer count = redisService.load(key, Integer.class);
        if (count < limit.limit()) {
            //计数器+1
            redisService.update(key, count + 1);
            return true;
        }
        return false;
    }
}
